//
//  RACAndMVVMViewController02.m
//  RACExample
//
//  Created by 山刘 on 2020/5/29.
//  Copyright © 2020 山刘. All rights reserved.
//

#import "RACAndMVVMViewController02.h"
#pragma mark - ====================VM层====================
@interface RACAndMVVMViewModel02 : NSObject
@property(nonatomic, strong) NSString *email;
@property(nonatomic, strong) NSString *statusMessage;
@property(nonatomic, strong) RACCommand *subscribeCommand;
@end
@implementation RACAndMVVMViewModel02
-(instancetype)init{
    if (self == [super init]) {
        [self rac_init];
    }
    return self;
}
-(void)rac_init{
    @weakify(self)
    RACSignal *emailSignal = [[RACObserve(self, email) map:^id _Nullable(NSString*  _Nullable value) {
        @strongify(self)
        return @([self isValidEmail:value]);
    }]distinctUntilChanged];
    
    [emailSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    self.subscribeCommand = [[RACCommand alloc] initWithEnabled:emailSignal signalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        @strongify(self)
        return [self businessOperation:self.email];
    }];
    
    RACSignal *rac1 = [self.subscribeCommand.executionSignals map:^id _Nullable(id  _Nullable value) {
        NSLog(@"Request");
        return @"Request";
    }];
    RACSignal *rac2 = [self.subscribeCommand.executionSignals flattenMap:^__kindof RACSignal * _Nullable(RACSignal* signal) {
        return [[[signal materialize]filter:^BOOL(RACEvent *event) {
            NSLog(@"... RACEventType:%zd",event.eventType);
            return event.eventType == RACEventTypeCompleted;
        }] map:^id _Nullable(id  _Nullable value) {
            NSLog(@"Thanks!");
            return @"Thanks!";
        }];
    }];
    RACSignal *rac3 = [[self.subscribeCommand.errors subscribeOn:[RACScheduler mainThreadScheduler]] map:^id _Nullable(NSError * _Nullable value) {
        NSLog(@"Error");
        return @"Error";
    }];
    RAC(self,statusMessage) = [RACSignal merge:@[rac1,rac2,rac3]];
}

// 处理业务逻辑
-(RACSignal*)businessOperation:(NSString*)content{
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSLog(@"Loading...");
        [subscriber sendNext:@"Loading..."];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [subscriber sendError:nil];
        });
        return [RACDisposable disposableWithBlock:^{
        }];
    }];
}

// 检测strin是否是邮件
- (BOOL)isValidEmail:(NSString*)content {
    if (!content) return NO;
    
    NSString *emailPattern =
    @"(?:[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[a-z0-9!#$%\\&'*+/=?\\^_`{|}"
    @"~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\"
    @"x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-"
    @"z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5"
    @"]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-"
    @"9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21"
    @"-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";
    NSError *error = nil;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:emailPattern options:NSRegularExpressionCaseInsensitive error:&error];
    NSTextCheckingResult *match = [regex firstMatchInString:content options:0 range:NSMakeRange(0, [content length])];
    return match != nil;
}
@end
#pragma mark - ====================V层====================
@interface RACAndMVVMViewController02 ()
@property (weak, nonatomic) IBOutlet UITextField *inputTextField;
@property (weak, nonatomic) IBOutlet UIButton *loginButton;
@property (weak, nonatomic) IBOutlet UILabel *statusLabel;
@property(nonatomic, strong) RACAndMVVMViewModel02 *viewModel;
@end

@implementation RACAndMVVMViewController02

- (void)viewDidLoad {
    [super viewDidLoad];
    [self bindViewModel];
}

#pragma mark - RAC Data Binding
- (void)bindViewModel {
    RAC(self.viewModel,email) = self.inputTextField.rac_textSignal;
    RAC(self.statusLabel,text) = RACObserve(self.viewModel, statusMessage);
    self.loginButton.rac_command = self.viewModel.subscribeCommand;
}

#pragma mark - getter
-(RACAndMVVMViewModel02 *)viewModel{
    if (!_viewModel) {
        _viewModel = [RACAndMVVMViewModel02 new];
    }
    return _viewModel;
}
@end
